﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKArchUtils.Utils;

namespace YJKRevitWallModule.WallModule.EditWall
{
	public class WallControler
	{
		public WallControler(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
		}

		public Result SearchOutWalls(ref string msg)
		{
			WallSearchManager wallSearchManager = new WallSearchManager(this.m_Revit);
			List<WallData> outWallDataList = new List<WallData>();
			wallSearchManager.Search(true, ref outWallDataList);
			Transaction transaction = null;
			Result result;
			try
			{
				transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
				transaction.Start("Search Out Walls");
				this.HighlightWall(outWallDataList);
				transaction.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				msg = ex.Message;
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		public Result SearchInternalWalls(ref string msg)
		{
			WallSearchManager wallSearchManager = new WallSearchManager(this.m_Revit);
			List<WallData> outWallDataList = new List<WallData>();
			wallSearchManager.Search(false, ref outWallDataList);
			Transaction transaction = null;
			Result result;
			try
			{
				transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
				transaction.Start("Search Internal Walls");
				RevitVersionFuncs.ClearSelection(this.m_Revit.Application.ActiveUIDocument.Selection);
				this.HighlightWall(outWallDataList);
				transaction.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				msg = ex.Message;
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		public Result OutWallsChangeType(ref string msg)
		{
			ChangeOutWallTypeForm changeOutWallTypeForm = new ChangeOutWallTypeForm(this.m_Revit);
			if (changeOutWallTypeForm.ShowDialog() != DialogResult.OK)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			if (changeOutWallTypeForm.SelectWallType == null)
			{
				msg = "墙类型为空";
				return Autodesk.Revit.UI.Result.Failed;
			}
			List<ElementId> selectedWallsId = new List<ElementId>();
			if (changeOutWallTypeForm.SelectOutWall && !this.SelectWalls(ref selectedWallsId))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			WallSearchManager wallSearchManager = new WallSearchManager(this.m_Revit);
			List<WallData> outWallDataList = new List<WallData>();
			wallSearchManager.Search(true, ref outWallDataList);
			if (changeOutWallTypeForm.SelectOutWall)
			{
				this.FilterWall(selectedWallsId, ref outWallDataList);
			}
			Result result = this.ShowOutWallInfo(outWallDataList, ref msg);
			if (result != Autodesk.Revit.UI.Result.Succeeded)
			{
				return result;
			}
			result = this.ChangeWallType(outWallDataList, changeOutWallTypeForm.SelectWallType, ref msg);
			if (result != Autodesk.Revit.UI.Result.Succeeded)
			{
				return result;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result ShowOutWallInfo(List<WallData> outWallDataList, ref string msg)
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(document);
				transaction.Start("Out Walls Change Type");
				this.HighlightWall(outWallDataList);
				List<ElementId> searchedWall = this.GetSearchedWall(outWallDataList);
				ViewResultsForm viewResultsForm = new ViewResultsForm(this.m_Revit.Application.ActiveUIDocument, searchedWall);
				viewResultsForm.SetOutput("是否更改当前高亮显示的外墙");
				if (viewResultsForm.ShowDialog() != DialogResult.OK)
				{
					this.UnHighlightWall();
					if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
					{
						transaction.RollBack();
					}
					return Autodesk.Revit.UI.Result.Cancelled;
				}
				this.UnHighlightWall();
				transaction.Commit();
			}
			catch (Exception ex)
			{
				msg = ex.Message;
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result ChangeWallType(List<WallData> outWallDataList, WallType wallType, ref string msg)
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(document);
				transaction.Start("Out Walls Type Changing");
				foreach (WallData wallData in outWallDataList)
				{
					(this.m_Revit.Application.ActiveUIDocument.Document.GetElement(wallData.Id) as Wall).WallType = wallType;
				}
				transaction.Commit();
			}
			catch (Exception ex)
			{
				msg = ex.Message;
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result ChangeWallJoinEnds(List<WallData> outWallDataList, bool isDisallow)
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(document);
				transaction.Start("join ends");
				foreach (WallData wallData in outWallDataList)
				{
					Wall wall = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(wallData.Id) as Wall;
					if (isDisallow)
					{
						WallUtils.DisallowWallJoinAtEnd(wall, 0);
						WallUtils.DisallowWallJoinAtEnd(wall, 1);
					}
					else
					{
						WallUtils.AllowWallJoinAtEnd(wall, 0);
						WallUtils.AllowWallJoinAtEnd(wall, 1);
					}
				}
				this.UpdateModel(this.m_Revit.Application.ActiveUIDocument, true);
				transaction.Commit();
			}
			catch (Exception)
			{
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public Result OutWallsFlipFacing(ref string msg)
		{
			WallSearchManager wallSearchManager = new WallSearchManager(this.m_Revit);
			List<WallData> list = new List<WallData>();
			wallSearchManager.Search(true, ref list);
			Transaction transaction = null;
			Result result;
			try
			{
				transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
				transaction.Start("Out Walls FlipFacing");
				List<Wall> list2 = new List<Wall>();
				List<ElementId> list3 = new List<ElementId>();
				foreach (WallData wallData in list)
				{
					Wall wall = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(wallData.Id) as Wall;
					if (wall != null)
					{
						XYZ orientation = wall.Orientation;
						XYZ ptOut = null;
						if (wallData.GetOrientation(true, ref ptOut))
						{
							double angle = Geometry.getAngle(XYZ.Zero, ptOut);
							double angle2 = Geometry.getAngle(XYZ.Zero, orientation);
							if (Geometry.GreaterThan(Geometry.IntersectionAngle(angle, angle2), Math.PI*.5))
							{
								list2.Add(wall);
								list3.Add(wall.Id);
							}
						}
					}
				}
				this.HighlightWall(list2);
				ViewResultsForm viewResultsForm = new ViewResultsForm(this.m_Revit.Application.ActiveUIDocument, list3);
				viewResultsForm.SetOutput("是否更改当前高亮显示的外墙");
				if (viewResultsForm.ShowDialog() != DialogResult.OK)
				{
					this.UnHighlightWall();
					if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
					{
						transaction.RollBack();
					}
					result = Autodesk.Revit.UI.Result.Cancelled;
				}
				else
				{
					int refParameter = 1;
					foreach (Wall wall2 in list2)
					{
						int refParameter2 = this.ChangeRefParameter(wall2, refParameter);
						wall2.Flip();
						this.ChangeRefParameter(wall2, refParameter2);
					}
					this.UnHighlightWall();
					transaction.Commit();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
			}
			catch (Exception ex)
			{
				msg = ex.Message;
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		public int ChangeRefParameter(Wall wall, int refParameter)
		{
			int num = 1;
			int result;
			try
			{
				Parameter parameter = wall.GetParameter(BuiltInParameter.WALL_KEY_REF_PARAM);
				if (parameter == null)
				{
					result = num;
				}
				else
				{
					num = parameter.AsInteger();
					parameter.Set(refParameter);
					result = num;
				}
			}
			catch (Exception)
			{
				result = num;
			}
			return result;
		}

		public Result WallsOffset(bool isOutWall, ref string msg)
		{
			bool flag;
			WallRefLineType theWallRefLineType;
			if (isOutWall)
			{
				OutWallOffsetForm outWallOffsetForm = new OutWallOffsetForm();
				if (outWallOffsetForm.ShowDialog() != DialogResult.OK)
				{
					return Autodesk.Revit.UI.Result.Cancelled;
				}
				flag = outWallOffsetForm.SelectOutWall;
				theWallRefLineType = outWallOffsetForm.TheWallRefLineType;
			}
			else
			{
				OffsetInternalWallForm offsetInternalWallForm = new OffsetInternalWallForm();
				if (offsetInternalWallForm.ShowDialog() != DialogResult.OK)
				{
					return Autodesk.Revit.UI.Result.Cancelled;
				}
				flag = offsetInternalWallForm.SelectWall;
				theWallRefLineType = offsetInternalWallForm.TheWallRefLineType;
			}
			List<ElementId> selectedWallsId = new List<ElementId>();
			if (flag && !this.SelectWalls(ref selectedWallsId))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			WallSearchManager wallSearchManager = new WallSearchManager(this.m_Revit);
			List<WallData> list = new List<WallData>();
			wallSearchManager.Search(isOutWall, ref list);
			this.FilterWall(theWallRefLineType, ref list);
			if (flag)
			{
				this.FilterWall(selectedWallsId, ref list);
			}
			Transaction transaction = null;
			Result result;
			try
			{
				transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
				transaction.Start("Walls Offset");
				this.HighlightWall(list);
				List<ElementId> searchedWall = this.GetSearchedWall(list);
				ViewResultsForm viewResultsForm = new ViewResultsForm(this.m_Revit.Application.ActiveUIDocument, searchedWall);
				viewResultsForm.SetOutput("是否更改当前高亮显示的墙");
				if (viewResultsForm.ShowDialog() != DialogResult.OK)
				{
					this.UnHighlightWall();
					if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
					{
						transaction.RollBack();
					}
					result = Autodesk.Revit.UI.Result.Cancelled;
				}
				else
				{
					if (isOutWall)
					{
						Result result2 = this.OffsetOutWalls(list, theWallRefLineType);
						if (result2 != Result.Succeeded)
						{
							return result2;
						}
					}
					else
					{
						Result result3 = this.OffsetInternalWalls(list, (int)theWallRefLineType);
                        if (result3 != Result.Succeeded)
						{
							return result3;
						}
					}
					this.UnHighlightWall();
					transaction.Commit();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
			}
			catch (Exception ex)
			{
				msg = ex.Message;
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		private Result OffsetOutWalls(List<WallData> wallDataList, WallRefLineType TheWallRefLineType)
		{
			WallEditor wallEditor = new WallEditor(this.m_Revit);
			List<Curve> offsetedCurveList = new List<Curve>();
			List<XYZ> list = new List<XYZ>();
			Result offsetCurveList = this.GetOffsetCurveList(wallDataList, (int)TheWallRefLineType, wallEditor, ref offsetedCurveList, ref list);
			if (offsetCurveList != null)
			{
				return offsetCurveList;
			}
			List<XYZ> list2 = new List<XYZ>();
			List<XYZ> list3 = new List<XYZ>();
			this.GetNewVertexList(wallDataList, offsetedCurveList, ref list2, ref list3);
			for (int i = 0; i < wallDataList.Count; i++)
			{
				WallData wallData = wallDataList[i];
				Wall wall = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(wallData.Id) as Wall;
				if (wall != null)
				{
					XYZ newStartPoint = list2[i];
					XYZ newEndPoint = list3[i];
					wallEditor.Offset(wall, list[i], newStartPoint, newEndPoint);
				}
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result OffsetInternalWalls(List<WallData> wallDataList, int wallRefLineType)
		{
			foreach (WallData wallData in wallDataList)
			{
				Wall wall = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(wallData.Id) as Wall;
				if (wall != null)
				{
					XYZ xyz = null;
					if (wallData.GetOrientation(false, ref xyz))
					{
                        WallLocationLine locationLine = (WallLocationLine)wall.get_Parameter(BuiltInParameter.WALL_KEY_REF_PARAM).AsInteger();
						wall.WallType.GetCompoundStructure();
						CompoundStructureLayerAnalyzer.OffsetForWallLocationLine offsetStruct = CompoundStructureLayerAnalyzer.AnalyzerOffset(wall);
						double offsetForLocationLine = CompoundStructureLayerAnalyzer.GetOffsetForLocationLine(locationLine, offsetStruct);
                        double offsetForLocationLine2 = CompoundStructureLayerAnalyzer.GetOffsetForLocationLine((WallLocationLine)wallRefLineType, offsetStruct);
						double num = offsetForLocationLine - offsetForLocationLine2;
						wall.get_Parameter(BuiltInParameter.WALL_KEY_REF_PARAM).Set(wallRefLineType);
						Curve curve = null;
						WallUtils.DisallowWallJoinAtEnd(wall, 0);
						WallUtils.DisallowWallJoinAtEnd(wall, 1);
						if (!this.GetOffsetCurve(wall, xyz * num, ref curve))
						{
							WallUtils.AllowWallJoinAtEnd(wall, 0);
							WallUtils.AllowWallJoinAtEnd(wall, 1);
						}
						else
						{
							(wall.Location as LocationCurve).Curve = curve;
							WallUtils.AllowWallJoinAtEnd(wall, 0);
							WallUtils.AllowWallJoinAtEnd(wall, 1);
						}
					}
				}
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result GetOffsetCurveList(List<WallData> outWallDataList, int wallRefLineType, WallEditor editor, ref List<Curve> offsetedCurveList, ref List<XYZ> offsetDirectionList)
		{
			foreach (WallData wallData in outWallDataList)
			{
				Wall wall = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(wallData.Id) as Wall;
				if (wall != null)
				{
					XYZ xyz = null;
					if (wallData.GetOrientation(true, ref xyz))
					{
                        WallLocationLine locationLine = (WallLocationLine)wall.get_Parameter(BuiltInParameter.WALL_KEY_REF_PARAM).AsInteger();
						wall.WallType.GetCompoundStructure();
						CompoundStructureLayerAnalyzer.OffsetForWallLocationLine offsetStruct = CompoundStructureLayerAnalyzer.AnalyzerOffset(wall);
						double offsetForLocationLine = CompoundStructureLayerAnalyzer.GetOffsetForLocationLine(locationLine, offsetStruct);
                        double offsetForLocationLine2 = CompoundStructureLayerAnalyzer.GetOffsetForLocationLine((WallLocationLine)wallRefLineType, offsetStruct);
						double num = offsetForLocationLine - offsetForLocationLine2;
						wall.get_Parameter(BuiltInParameter.WALL_KEY_REF_PARAM).Set(wallRefLineType);
						Curve item = null;
						if (!editor.OffsetCurve(wall, xyz * num, ref item))
						{
							return Autodesk.Revit.UI.Result.Failed;
						}
						offsetedCurveList.Add(item);
						offsetDirectionList.Add(xyz * num);
					}
				}
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private bool GetOffsetCurve(Wall wall, XYZ offsetDirection, ref Curve offsetedCurve)
		{
			bool result;
			try
			{
				Curve curve = (wall.Location as LocationCurve).Curve;
				if (curve.GetType() == typeof(Line))
				{
					Line curve2 = curve as Line;
					XYZ xyz = curve2.GetEndPoint(0);
					XYZ xyz2 = curve2.GetEndPoint(1);
					xyz += offsetDirection;
					xyz2 += offsetDirection;
					offsetedCurve = YJKLineEx.YJKGetBound(xyz, xyz2);
				}
				else
				{
					if (!(curve.GetType() == typeof(Arc)))
					{
						return false;
					}
					Arc arc = curve as Arc;
					XYZ xyz3 = arc.GetEndPoint(0);
					XYZ xyz4 = arc.GetEndPoint(1);
					XYZ center = arc.Center;
					XYZ xyz5 = Geometry.CalculatMidPoint(xyz3, xyz4, center, arc.Normal);
					XYZ xyz6 = (xyz5 - center).Normalize();
					double num = offsetDirection.GetLength();
					double angle = Geometry.getAngle(XYZ.Zero, xyz6);
					double angle2 = Geometry.getAngle(XYZ.Zero, offsetDirection);
					if (Geometry.GreaterThan(Geometry.IntersectionAngle(angle, angle2), Math.PI*.5))
					{
						num = -num;
					}
					XYZ xyz7 = xyz6 * num;
					xyz5 += xyz7;
					xyz7 = (xyz3 - center).Normalize() * num;
					xyz3 += xyz7;
					xyz7 = (xyz4 - center).Normalize() * num;
					xyz4 += xyz7;
					offsetedCurve = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(xyz3, xyz4, xyz5);
				}
				result = true;
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				result = false;
			}
			return result;
		}

		private void GetNewVertexList(List<WallData> outWallDataList, List<Curve> offsetedCurveList, ref List<XYZ> ptNewStartVertexList, ref List<XYZ> ptNewEndVertexList)
		{
			for (int i = 0; i < offsetedCurveList.Count; i++)
			{
				Curve curve = offsetedCurveList[i];
				ptNewStartVertexList.Add(curve.GetEndPoint(0));
				ptNewEndVertexList.Add(curve.GetEndPoint(1));
			}
			for (int i = 0; i < offsetedCurveList.Count; i++)
			{
				Curve curve2 = offsetedCurveList[i];
				for (int j = i + 1; j < offsetedCurveList.Count; j++)
				{
					Curve curve3 = offsetedCurveList[j];
					if (outWallDataList[i].Linked(outWallDataList[j]))
					{
						bool flag = false;
						bool flag2 = false;
						XYZ curNode = this.NearPoint(curve2, curve3, ref flag, ref flag2);
						XYZ xyz = Geometry.IntersectWithTwoCurves(curve2, curve3, curNode, true, true, this.m_Revit.Application.Application);
						if (xyz != null)
						{
							if (flag)
							{
								ptNewStartVertexList[i] = xyz;
							}
							else
							{
								ptNewEndVertexList[i] = xyz;
							}
							if (flag2)
							{
								ptNewStartVertexList[j] = xyz;
							}
							else
							{
								ptNewEndVertexList[j] = xyz;
							}
						}
					}
				}
			}
		}

		private XYZ NearPoint(Curve curve1, Curve curve2, ref bool curve1Start, ref bool curve2Start)
		{
			XYZ hyendPoint = curve1.GetEndPoint(0);
			XYZ hyendPoint2 = curve1.GetEndPoint(1);
			XYZ hyendPoint3 = curve2.GetEndPoint(0);
			XYZ hyendPoint4 = curve2.GetEndPoint(1);
			double num = hyendPoint.DistanceTo(hyendPoint3);
			double num2 = hyendPoint.DistanceTo(hyendPoint4);
			double num3 = hyendPoint2.DistanceTo(hyendPoint3);
			double num4 = hyendPoint2.DistanceTo(hyendPoint4);
			List<double> list = new List<double>();
			list.Add(num);
			list.Add(num2);
			list.Add(num3);
			list.Add(num4);
			list.Sort();
			XYZ result = null;
			if (Geometry.IsEqual(list[0], num))
			{
				result = Geometry.CalculatMidPoint(hyendPoint, hyendPoint3);
				curve1Start = true;
				curve2Start = true;
			}
			else if (Geometry.IsEqual(list[0], num2))
			{
				result = Geometry.CalculatMidPoint(hyendPoint, hyendPoint4);
				curve1Start = true;
				curve2Start = false;
			}
			else if (Geometry.IsEqual(list[0], num3))
			{
				result = Geometry.CalculatMidPoint(hyendPoint2, hyendPoint3);
				curve1Start = false;
				curve2Start = true;
			}
			else if (Geometry.IsEqual(list[0], num4))
			{
				result = Geometry.CalculatMidPoint(hyendPoint2, hyendPoint4);
				curve1Start = false;
				curve2Start = false;
			}
			return result;
		}

		private bool SelectWalls(ref List<ElementId> wallsId)
		{
			IList<Reference> list = null;
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				list = selection.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, new YJKRevitWallModule.WallModule.EditWall.WallFilter(), "区域选择");
			}
			catch (Exception)
			{
				return false;
			}
			foreach (Reference reference in list)
			{
				Wall wall = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(reference) as Wall;
				if (wall != null)
				{
					wallsId.Add(wall.Id);
				}
			}
			return true;
		}

		private void FilterWall(WallRefLineType wallRefLineType, ref List<WallData> wallDataList)
		{
			for (int i = 0; i < wallDataList.Count; i++)
			{
				WallData wallData = wallDataList[i];
				Wall wall = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(wallData.Id) as Wall;
				if (wall.WallType.Kind != 0)
				{
					wallDataList.RemoveAt(i);
					i--;
				}
				else if (!wall.ParametersMap.Contains("已附着顶部") && !wall.ParametersMap.Contains("Top is Attached"))
				{
					wallDataList.RemoveAt(i);
					i--;
				}
				else
				{
					Parameter parameter = wall.GetParameter(BuiltInParameter.WALL_KEY_REF_PARAM);
                    int wallType2 = parameter.AsInteger();
                    int wallType3 = (int)wallRefLineType;


					if (parameter != null && parameter.AsInteger() == (int)wallRefLineType)
					{
						wallDataList.RemoveAt(i);
						i--;
					}
				}
			}
		}

		private void FilterWall(List<ElementId> selectedWallsId, ref List<WallData> wallDataList)
		{
			for (int i = 0; i < wallDataList.Count; i++)
			{
				WallData wallData = wallDataList[i];
				int id = wallData.Id.IntegerValue;
				if (selectedWallsId.FindIndex((ElementId s) => s.IntegerValue == id) == -1)
				{
					wallDataList.RemoveAt(i);
					i--;
				}
			}
		}

		private List<ElementId> GetSearchedWall(List<WallData> wallDataList)
		{
			List<ElementId> list = new List<ElementId>();
			foreach (WallData wallData in wallDataList)
			{
				list.Add(wallData.Id);
			}
			return list;
		}

		private void HighlightWall(List<WallData> outWallDataList)
		{
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			List<Element> list = new List<Element>();
			foreach (WallData wallData in outWallDataList)
			{
				Element element = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(wallData.Id);
				list.Add(element);
			}
			RevitVersionFuncs.SetSelection(selection, list);
		}

		private void HighlightWall(List<Wall> outWallList)
		{
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			List<Element> list = new List<Element>();
			foreach (Wall item in outWallList)
			{
				list.Add(item);
			}
			RevitVersionFuncs.SetSelection(selection, list);
		}

		private void UnHighlightWall()
		{
			RevitVersionFuncs.ClearSelection(this.m_Revit.Application.ActiveUIDocument.Selection);
		}

		private void UpdateModel(UIDocument uiDoc, bool autoJoin)
		{
			uiDoc.Document.Regenerate();
			if (autoJoin)
			{
				uiDoc.Document.AutoJoinElements();
			}
			uiDoc.RefreshActiveView();
		}

		private ExternalCommandData m_Revit;
	}
}
